package main

import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"gitee.com/ling-bin/network/netInterface"
	"gitee.com/ling-bin/network/netService"
	"io/ioutil"
	"log"
	"net"
	"os"
	"runtime"
	"time"
)

func main() {
	addrs, err := net.InterfaceAddrs()
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	port := []string{"7015", "7016", "7017", "7018", "7019", "7020"} //监听端口
	addrAry := make([]string, 0, 5)
	for _, address := range addrs {
		if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
			if ipnet.IP.To4() != nil {
				for _, val := range port {
					addrAry = append(addrAry, ipnet.IP.String()+":"+val)
				}
			}
		}
	}
	for _, val := range port {
		addrAry = append(addrAry, fmt.Sprint("127.0.0.1:", val))
	}

	addrAryConfig := make([]*netService.AddrConfig, 0, len(addrAry))

	certFile := "D:\\Project\\GoProject\\network\\apps\\server.pem"
	keyFile := "D:\\Project\\GoProject\\network\\apps\\server.key"
	clientCer := "D:\\Project\\GoProject\\network\\apps\\client.pem"

	for _, val := range addrAry {
		//TLS网络监听
		crt, err := tls.LoadX509KeyPair(certFile, keyFile)
		if err != nil {
			log.Println("[TLS]读取证书异常 [Cert=", certFile, " Key=", keyFile, "]")
			return
		}
		//配置了客户端使用的证书强制验证
		tlsConfig := &tls.Config{}
		if clientCer != "" {
			certBytes, err := ioutil.ReadFile(clientCer)
			if err != nil {
				log.Println("[TLS]读取客户端证书异常 [Cert=", certFile, " Key=", keyFile, "]")
				return
			}
			clientCertPool := x509.NewCertPool()
			ok := clientCertPool.AppendCertsFromPEM(certBytes)
			if !ok {
				log.Println("[TLS]添加客户端证书异常 [Cert=", certFile, " Key=", keyFile, "]")
				return
			}
			/*客户端证书验证模式*/
			tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert
			tlsConfig.ClientCAs = clientCertPool
		}
		tlsConfig.Certificates = []tls.Certificate{crt}
		addrAryConfig = append(addrAryConfig, &netService.AddrConfig{
			Addr:      val,
			TlsConfig: tlsConfig,
			IsTls:     true,
		})
	}
	config := netService.NewConfig("tcp", addrAryConfig)
	service := netService.NewService(config)
	service.SetOnConnStart(func(connection netInterface.IConnection) {
		//connId := connection.GetConnId()
		//fmt.Println("[", connection.GetRemoteAddr().String(), "]新连接：", connId)
	})
	service.SetOnConnStop(func(connection netInterface.IConnection) {
		//connId := connection.GetConnId()
		//fmt.Println("[", connection.GetRemoteAddr().String(), "]连接关闭：", connId)
	})
	count := int64(0)
	countErr := int64(0)
	//设置接收到完整包回调
	service.SetOnReceive(func(connection netInterface.IConnection, data []byte) {
		connId := connection.GetConnId()
		//fmt.Println("[",connection.GetRemoteAddr().String(),"][" , connId , "]连接上传新数据：" , len(data),"---",string(data))
		sendBf := []byte(fmt.Sprint("(tls ", connId, " service  ", len(data), "!)"))
		err := connection.SendData(sendBf, "")
		if err != nil {
			fmt.Println("下发异常：", err)
		}
		if len(data) != 8{
			fmt.Println("数据包异常")
			countErr++
		}else {
			count++
		}
		//connection.SendDataCall(sendBf,"测试", func(connection netInterface.IConnection, b bool, param interface{}, err error) {
		//	fmt.Println("下发回调：",param)
		//})
		//fmt.Println("启动时间：",connection.GetStartTime())
		//fmt.Println("心跳时间：",connection.GetHeartTime())
		//fmt.Println("上行信息：")
		//fmt.Println(connection.GetRecInfo())
		//fmt.Println("下行信息：")
		//fmt.Println(connection.GetRepInfo())
	})

	//设置下发回调
	service.SetOnReply(func(connection netInterface.IConnection, data []byte, isOk bool, cmdCode string, param interface{}, err error) {
		//connId := connection.GetConnId()
		//fmt.Println("[",connection.GetRemoteAddr().String(),"][" , connId , "]连接下发数据[",connection.GetPackCount(),"]：" , len(data),"---",string(data))
		if !isOk {
			log.Println("数据下发异常：", err)
		}
		//fmt.Println("全局回调：",param)
	})

	service.SetLogHandle(func(level netInterface.ErrLevel, msg ...interface{}) {
		switch level {
		case netInterface.Fatal:
			log.Panicln("[致命]", msg)
			break
		case netInterface.Error:
			log.Println("[错误]", msg)
			break
		case netInterface.Warn:
			log.Println("[警告]", msg)
			break
		case netInterface.Info:
			log.Println("[消息]", msg)
			break
		}
	})
	go func() {
		for {
			log.Println(count)
			log.Println(countErr)
			log.Println(
				"[---TLS---]启动时间:", service.GetStartTime().Format("2006-01-02 15:04:05"),
				" 连接数:", service.GetConnMgr().Count(),
				" 协程数：", runtime.NumGoroutine())
			time.Sleep(time.Second * 2)
		}
	}()
	service.Start()
	select {}
}
